//
//  HMStatusDAL.swift
//  大深圳微博01
//
//  Created by shenzhenIOS on 16/4/23.
//  Copyright © 2016年 shenzhenIOS. All rights reserved.
//

import UIKit

// 专门加载微博数据,本地或服务器

/*
    微博数据缓存流程:
        1.查看本地数据库是否保存数据 *
        2.如果本地数据有数据直接使用本地数据库的数据
        3.本地没有数据,发送网络请求,去服务器加载数据
        4.将服务器返回的数据保存到本地 *
        5.在将服务器返回的数据,返回给别人处理
*/
class HMStatusDAL: NSObject {
    static let sharedDAL: HMStatusDAL = HMStatusDAL()
    
    private let overTime: NSTimeInterval = 60 // 7 * 24 * 60 * 60 // 秒数
    
    private override init() {
        super.init()
    }
    
    /// 删除过期的微博数据
    func deleteCacheStatus() {
        // 计算过期时间 7天前
        let overDate = NSDate(timeIntervalSinceNow: -overTime)
        
        let df = NSDateFormatter()
        df.locale = NSLocale(localeIdentifier: "EN")
        
        // 2016-04-23 21:17:42
        df.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let overStrig = df.stringFromDate(overDate)
        print("overStrig: \(overStrig)")
        
        let sql = "DELETE FROM T_Status WHERE createTime < '\(overStrig)';"
        
        HMSQLiteManager.sharedManager.dbQueue.inDatabase { (db) -> Void in
            do {
                try db.executeUpdate(sql, values: [])
                print("清除缓存成功")
            } catch let error as NSError {
                print("清除缓存失败: \(error)")
            }
            
        }
    }
    
    /// 加载微博数据,可能从服务器,也可能从数据库加载
    func loadStatus(since_id: Int64, max_id: Int64, loadStatusCallback: (status: [[String: AnyObject]]?, error: NSError?) -> ()) {
        // 1.查看本地数据库是否保存数据 *
        loadCacheStatus(since_id, max_id: max_id) { (status) -> () in
            if status != nil && status!.count > 0 {
                print("本地有微博数据")
                // 2.本地数据有数据直接使用本地数据库的数据
                loadStatusCallback(status: status, error: nil)
                return
            }
            
            // 3.本地没有数据,发送网络请求,去服务器加载数据
            // 1.urlString
            let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
            
            // 2.参数
            /// [String : String?]: key是String类型,value是String或nil,数组或字典中的元素不能为nil
            var parameters: [String: AnyObject] = ["access_token": HMUserAccountViewModel.sharedInstance.userAccount!.access_token!]
            
            // 将since_id, max_id拼接到请求参数里面
            if since_id > 0 {   // 别人转了since_id
                parameters["since_id"] = NSNumber(longLong: since_id)
            } else if max_id > 0 {
                // 返回ID小于或等于max_id的微博, 不需要等于max_id的这条微博 max_id - 1
                parameters["max_id"] = NSNumber(longLong: max_id - 1)
            }
            
            // 3.发送请求
            HMNetworkTool.sharedInstance.GET(urlString, parameters: parameters, progress: nil, success: { (_, responseObject) -> Void in
                
                // 获取微博数据
                // 看是否能转成字典, 获取字典里面的内容
                if let dict = responseObject as? [String: AnyObject], let statusesDict = dict["statuses"] as? [[String: AnyObject]] {
                    // 4.将服务器返回的数据保存到本地 *
                    self.saveCacheStatus(statusesDict)
                    
                    // 5.在将服务器返回的数据,返回给别人处理
                    loadStatusCallback(status: statusesDict, error: nil)
                }
                
                }, failure: { (_, error) -> Void in
                    loadStatusCallback(status: nil, error: error)
            })
        }
    }
    
    /// 从本地数据库加载微博数据
    private func loadCacheStatus(since_id: Int64, max_id: Int64, loadCacheStatusCallback: (status: [[String: AnyObject]]?) -> ()) {
        // 获取UID
        let uid = HMUserAccountViewModel.sharedInstance.userAccount?.uid
        
        assert(uid != nil, "没有uid")
        
        var sql = "SELECT status_id, status, user_id FROM T_Status \n" + "WHERE user_id = \(uid!) \n"
        
        if since_id > 0 {
            // 下拉刷新
            sql += "AND status_id > \(since_id) \n"
        } else if max_id > 0 {
            // 上拉加载
            sql += "AND status_id < \(max_id) \n"
        }
        
        sql += "ORDER BY status_id DESC LIMIT 20;"
        
        print("sql: \(sql)")
        
        // 查询数据
        HMSQLiteManager.sharedManager.dbQueue.inDatabase { (db) -> Void in
            do {
                let resultSet = try db.executeQuery(sql, values: [])
                
                // 定义字典保存数据库中加载的数据
                var statusDicts = [[String: AnyObject]]()
                
                while resultSet.next() {
                    let statusText = resultSet.stringForColumn("status")
                    
                    // 返回的是字典数组
                    // String -> NSData -> JSON
                    let data = statusText.dataUsingEncoding(NSUTF8StringEncoding)!
                    let statusDict = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! [String: AnyObject]
                    
                    statusDicts.append(statusDict)
                }
                
                // 将数据库加载的微博数据返回回去
                
                loadCacheStatusCallback(status: statusDicts)
            } catch let error as NSError {
                print("加载本地微博数据出错了: \(error)")
                loadCacheStatusCallback(status: nil)
            }
        }
    }
    
    /// 保存微博字典数据到数据库
    ///
    /// - parameter statuses: 要保存的微博字典数组
    private func saveCacheStatus(statuses: [[String: AnyObject]]) {
        
        // 获取UID
        let uid = HMUserAccountViewModel.sharedInstance.userAccount?.uid
        
        assert(uid != nil, "没有uid")
        
        let sql = "INSERT INTO T_Status (status_id, status, user_id) VALUES (?, ?, ?)"
        HMSQLiteManager.sharedManager.dbQueue.inTransaction { (db, rollback) -> Void in
            // 遍历获取每条微博字典
            do {
                for dict in statuses {
                    // 微博id
                    let id = dict["id"] as! Int
                    
                    // 微博字典不能直接保存到数据库中
                    // 字典 -> NSData -> String
                    let data = try NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions(rawValue: 0))
                    
                    let statusText = String(data: data, encoding: NSUTF8StringEncoding)!
                    
                    try db.executeUpdate(sql, values: [id, statusText, uid!])
                }
                
                print("保存了: \(statuses.count) 条微博")
            } catch let error as NSError {
                print("保存微博出错了: \(error)")
            }
        }
    }
}
